import java.util.*;

/**
 * @program: LeetCode
 * @description: LeetCode : 239. 滑动窗口最大值
 * @author: WXY
 * @create: 2023-01-16 11:34
 * @Version 1.0
 **/
public class Num239_maxSlidingWindow {
    public static int[] maxSlidingWindow1(int[] nums, int k) {
        if (nums.length == 1) return nums;
        int len = nums.length - k + 1;
        int[] ans = new int[len];
        int index = 0;
        MyQueue queue = new MyQueue();
        for (int i = 0; i < k; i++) {
            queue.add(nums[i]);
        }
        ans[index++] = queue.peek();
        for (int i = k; i < nums.length; i++) {
            queue.poll(nums[i - k]);
            queue.add(nums[i]);
            ans[index++] = queue.peek();
        }
        return ans;
    }

    public static int[] maxSlidingWindow(int[] arr, int w) {
        if (arr == null || arr.length < w || w < 1) {
            return null;
        }
        LinkedList<Integer> qmax = new LinkedList<>();
        int[] res = new int[arr.length - w + 1];
        int index = 0;
        for (int R = 0; R < arr.length; R++) {
            while (!qmax.isEmpty() && arr[qmax.peekLast()] < arr[R]) {
                qmax.pollLast();
            }
            qmax.addLast(R);
            if (qmax.peekFirst() == R - w) {
                qmax.pollFirst();
            }
            if (R >= w - 1) {
                res[index++] = arr[qmax.peekFirst()];
            }
        }
        return res;
    }

    public static int[] maxSlidingWindow2(int[] arr, int k) {
        if (arr == null || arr.length < k || k < 1) {
            return null;
        }
        int[] res = new int[arr.length - k + 1];
        int index = 0;
        ArrayDeque<Integer> deque = new ArrayDeque<>();
        for (int i = 0; i < arr.length; i++) {
            while (!deque.isEmpty() && deque.peek() < i - k + 1) {
                deque.poll();
            }
            while (!deque.isEmpty() && arr[deque.peekLast()] < arr[i]) {
                deque.pollLast();
            }
            deque.offer(i);
            if (i >= k - 1) {
                res[index++] = arr[deque.peek()];
            }
        }
        return res;
    }

    public static void main(String[] args) {
        int[] arr = {1 - 7, -8, 7, 5, 7, 1, 6, 0};
        int k = 3;
        int[] ints = maxSlidingWindow2(arr, k);
        for (int i : ints) {
            System.out.print(i + " ");
        }
    }

    public static class MyQueue {
        Deque<Integer> deque = new LinkedList<>();

        public void poll(int val) {
            if (!deque.isEmpty() && val == deque.peek()) {
                deque.poll();
            }
        }

        public void add(int val) {
            while (!deque.isEmpty() && val > deque.getLast()) {
                deque.removeLast();
            }
            deque.add(val);
        }

        public int peek() {
            return deque.peek();
        }
    }
}
